package com.nuoniu.sibanyun.service.finance.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.finance.VReceivePaymentMain;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.mapper.finance.VReceivePaymentMainMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.service.finance.IVReceivePaymentDetailService;
import com.nuoniu.sibanyun.service.finance.IVReceivePaymentMainService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 付款单主表 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2021-04-19
 */
@Service
public class VReceivePaymentMainServiceImpl extends ServiceImpl<VReceivePaymentMainMapper, VReceivePaymentMain> implements IVReceivePaymentMainService {

    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private ErpNumberSetMapper numberSetMapper;
    @Autowired
    private IErpAccountService erpAccountService;
    @Autowired
    private IVReceivePaymentDetailService paymentDetailService;

    @Override
    public String getCode(String sourceCode) {
        Integer companyId = UserThreadLocal.get().getCompanyId();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        ErpNumberSet numberSet = numberSetMapper.getByCode(sourceCode, companyId, currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getNewestCode(companyId, dateStr, sourceCode);
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    public void saveReceivable( VReceivePaymentMain paymentMain) {
        UserInfo userInfo = UserThreadLocal.get();
        if(paymentMain.getId() == null) {
            paymentMain.setCompanyId(userInfo.getCompanyId());
            paymentMain.setAccountId(erpAccountService.getCurrentAccountId());
            paymentMain.setVoucherCode(getCode(paymentMain.getDataSource()));
            paymentMain.setVerificationAmount(new BigDecimal(0.0));
            paymentMain.setCreateUserId(userInfo.getUserId());
            paymentMain.setVoucherState(-1);
            paymentMain.setCreateUserName(userInfo.getRealName());
        }else {
            VReceivePaymentMain receive = this.getById(paymentMain.getId());
            if(!userInfo.getCompanyId().equals(receive.getCompanyId())) {
                throw new NuoNiuException("你无此权限，请联系管理员");
            }

            paymentMain.setUpdateUserId(userInfo.getUserId());
            paymentMain.setUpdateUserName(userInfo.getRealName());
            paymentMain.setUpdateDate(LocalDateTime.now());
        }

        Boolean result = this.saveOrUpdate(paymentMain);
        if(result) {
            List<Long> detailIds = new ArrayList<>();
            paymentMain.getOrderDetailList().forEach(r -> {
                r.setCompanyId(userInfo.getCompanyId());
                r.setAccountId(paymentMain.getAccountId());
                r.setOrderId(paymentMain.getId().intValue());
                if(r.getId() != null) {
                    detailIds.add(r.getId());
                }
            });

            //删除明细
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("company_id", userInfo.getCompanyId());
            wrapper.eq("order_id", paymentMain.getId());
            if(detailIds.size() > 0) {
                wrapper.notIn("id", detailIds);
                paymentDetailService.remove(wrapper);
            }else {
                paymentDetailService.remove(wrapper);
            }
            //保存单据明细表
            paymentDetailService.saveOrUpdateBatch(paymentMain.getOrderDetailList());
        }
    }

    @Override
    public void examine(Long id, Integer status) {
        if(null == id || null == status ||  (status > 1 || status < 0) )throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VReceivePaymentMain paymentMain = this.getById(id);
        if(paymentMain == null) {
            throw new NuoNiuException("单据不存在");
        }
        if(!userInfo.getCompanyId().equals(paymentMain.getCompanyId())) {
            throw new NuoNiuException("你无此权限，请联系管理员");
        }

        if(status == 1){
            if(paymentMain.getVoucherState() < 0) throw new NuoNiuException("单据还未提交");
            if(paymentMain.getVoucherState() > 0) throw new NuoNiuException("单据已经审核");
        }else if(status == 0){
            if (paymentMain.getVoucherState() > 1)throw new NuoNiuException("不是审核状态，不能弃审");
        }

        paymentMain.setVoucherState(status);
        paymentMain.setReviewerDate(LocalDateTime.now());
        paymentMain.setReviewerUserId(userInfo.getUserId());
        paymentMain.setReviewerUserName(userInfo.getRealName());
        this.updateById(paymentMain);
    }

    @Override
    public void deleteById(Long id) {
        UserInfo userInfo = UserThreadLocal.get();
        VReceivePaymentMain paymentMain = this.getById(id);
        if(paymentMain == null) {
            throw new NuoNiuException("单据不存在");
        }

        if(!userInfo.getCompanyId().equals(paymentMain.getCompanyId())) {
            throw new NuoNiuException("你无此权限，请联系管理员");
        }

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_id", id);
        paymentDetailService.remove(wrapper);
        this.removeById(id);
    }

    @Override
    public void submit(Long id, Integer status) {
        if(null == id || null == status || (null != status && (status > 0 || status < -1 )))throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VReceivePaymentMain orderMain = this.getById(id);
        if( null == orderMain) throw new NuoNiuException("记录不存在");
        //校验状态
        Integer voucherState = orderMain.getVoucherState();
        if(status == 0){
            if (voucherState > -1) throw new NuoNiuException("该单据已经提交");
        }else if(status == -1){
            if (voucherState > 0) throw new NuoNiuException("该单据已经审核,请先弃审");
        }
        //提交
        orderMain.setVoucherState(status);
        orderMain.setSubmitDate(LocalDateTime.now());
        orderMain.setSubmitUserId(userInfo.getUserId());
        orderMain.setSubmitUserName(userInfo.getRealName());
        this.updateById(orderMain);
    }

}
